package main

type ST struct {
	Name string
}

func gen1() ST {
	s1 := ST{Name: "zhanglin"}
	return s1
}

func gen2() *ST {
	s2 := &ST{Name: "zhanglin"} // 逃逸
	return s2
}

func gen3() string {
	s3 := "abcd"
	return s3
}

func gen4() int {
	s4 := 100
	return s4
}

func gen5() {
	ch := make(chan int, 1)
	var a int = 1
	ch <- a
}

func gen6() {
	ch := make(chan *ST, 1)
	var a = &ST{Name: "zhanglin"} // 逃逸
	ch <- a
}

func gen7() []int {
	s := make([]int, 0) // 逃逸
	return s
}

func gen8() [8]int {
	s := [8]int{1, 2, 3, 4, 5, 6, 7, 8}
	return s
}

func gen9() map[string]int {
	m := make(map[string]int) // 会逃逸
	return m
}

func main() {
	//fmt.Println(gen1())  // 不能使用fmt.Println(gen1()), 因为Println()接受的参数是interface{}类型，会导致gen1()逃逸
	_ = gen1()
	_ = gen2()
	_ = gen3()
	_ = gen4()
	gen5()
	gen6()
	_ = gen7()
	_ = gen8()
	_ = gen9()
}

// go build -gcflags '-m -l' escape4.go
// ./escape4.go:13:8: &ST{...} escapes to heap
//./escape4.go:35:10: &ST{...} escapes to heap
//./escape4.go:40:11: make([]int, 0) escapes to heap
//可以看到结构体作为指针传递给外部调用时，是分配在堆上，而作为值传递时是分配在栈上，不会逃逸
